#ifndef QUAD_DOT_H
#define QUAD_DOT_H

#include "symbol.h"

/* | QUADS       | a1   | a2   | a3   | meaning                | */
/* |-------------+------+------+------+------------------------| */
/* |-------------+------+------+------+------------------------| */
/* | Q_GOTO      | null | null | addr | goto addr              | */
/* |-------------+------+------+------+------------------------| */
/* | Q_IFEQGOTO  | a    | b    | addr | if(a==b) goto addr     | */
/* |-------------+------+------+------+------------------------| */
/* | Q_IFNEQGOTO | a    | b    | addr | if(a!=b) goto addr     | */
/* |-------------+------+------+------+------------------------| */
/* | Q_IFGTGOTO  | a    | b    | addr | if(a>b) goto addr      | */
/* |-------------+------+------+------+------------------------| */
/* | Q_IFGEGOTO  | a    | b    | addr | if(a>=b) goto addr     | */
/* |-------------+------+------+------+------------------------| */
/* | Q_IFLTGOTO  | a    | b    | addr | if(a<b) goto addr      | */
/* |-------------+------+------+------+------------------------| */
/* | Q_IFLEGOTO  | a    | b    | addr | if(a<=b) goto addr     | */
/* |-------------+------+------+------+------------------------| */
/* | Q_ASSIGN    | s    | null | d    | d = s                  | */
/* |-------------+------+------+------+------------------------| */
/* | Q_PTASSIGN    | s    | d | ptOffset    | *(d+*ptOffset) = s                  | */
/* |-------------+------+------+------+------------------------| */
/* | Q_PTASSIGN_CST    | s    | d | offset    | *(d+offset) = s                  | */
/* |-------------+------+------+------+------------------------| */
/* | Q_NEGATE    | s    | null | d    | d = -s                 | */
/* |-------------+------+------+------+------------------------| */
/* | Q_ADDI      | a    | b    | d    | d=a+b                  | */
/* |-------------+------+------+------+------------------------| */
/* | Q_MULI      | a    | b    | d    | d=a*b                  | */
/* |-------------+------+------+------+------------------------| */
/* | Q_DIVI      | a    | b    | d    | d=a/b                  | */
/* |-------------+------+------+------+------------------------| */
/* | Q_MINI      | a    | b    | d    | d=a-b                  | */
/* |-------------+------+------+------+------------------------| */
/* | Q_READI     | null | null | d    | d=read()               | */
/* |-------------+------+------+------+------------------------| */
/* | Q_PRINTI    | a    | null | null | print(a)               | */
/* |-------------+------+------+------+------------------------| */
/* | Q_PRINTS    | s    | null | null | print(s)               | */
/* |-------------+------+------+------+------------------------| */
/* | Q_CALL      | y    | f    | n    | y=f(param1,..paramn)   |  CARE: ret in a1 there  */
/* |-------------+------+------+------+------------------------| */
/* | Q_PARAM     | x    | null | null | x param of coming call | */
/* |-------------+------+------+------+------------------------| */
/* | Q_END       | null | null | null | end of the program     | */
/* |-------------+------+------+------+------------------------| */
/* | Q_FUNCEND   | null | null | null | end of function        | */
/* |-------------+------+------+------+------------------------| */
/* | Q_LABEL     | addr | null | null | label to addr          | */

/* also, a3 is void* such that it can hold int as well (usefull for label and param number) */

/* when calling function, y can be null if no return */




#define NULL_ADDR NULL
enum quad_t
{
  Q_GOTO,
  Q_IFEQGOTO,
  Q_IFNEQGOTO,
  Q_IFGTGOTO,
  Q_IFGEGOTO,
  Q_IFLTGOTO,
  Q_IFLEGOTO,
  Q_ASSIGN,
  Q_PTASSIGN,
  Q_PTASSIGN_CST,
  Q_NEGATE,
  Q_ADDI,
  Q_MULI,
  Q_DIVI,
  Q_MINI,
  Q_READI,
  Q_PRINTI,
  Q_PRINTS,
  Q_CALL,
  Q_PARAM,
  Q_FUNCEND,
  Q_LABEL,
  Q_END
};




typedef struct quad
{
  enum quad_t type;
  symbol* a1;
  symbol* a2;
  void* a3;
} quad;

void printQuad (quad q);
quad newQuad (unsigned int type,symbol* a1,symbol* a2,void* a3);
void printQuadType(enum quad_t type);

#endif 
